home *** CD-ROM | disk | FTP | other *** search
/ Megarom / Megarom Macintosh CD Software (Quantum Leap)(1992).iso / COMMUNICATION / MUBBS112 / modems HSTV1.0.cpt / Modems Module HST / HST source / modems module HST.c
Text File  |  1992-01-27  |  10KB  |  325 lines

  1. /*
  2.  *  Modems Module.c
  3.  *
  4.  *    This program source code and it's compiled version is
  5.  *  Copyright (c) 1991 N. Hawthorn.
  6.  *  This program source code and it's compiled version IS NOT IN THE
  7.  *  PUBLIC DOMAIN ! Please read the "COPYRIGHT NOTICE / NH" file for details
  8.  *  regarding use of this program source code and it's compiled version.
  9.  *
  10.  *  This module's name is "modems", it's type is "MOD1",  use a resource mover
  11.  *  to assign a new number to it, that's why we name our modules !
  12.  *
  13.  *  I don't recomend sysops using "no carrier detect". A cable SHOULD be made.
  14.  *  However, this module handles even the lame mode. MUBBS will probably hang
  15.  *  most of the time, and MUBBS will look real stupid for this, but the code
  16.  *  is in. It just tries to hang up in every baud rate ! This is totally LAME !
  17.  *
  18.  *
  19.  *  This is where it all starts...
  20.  *
  21.  */
  22.  
  23. #define INMAIN
  24.  
  25. #include     <SetUpA4.h>
  26. #include    "MUBBS Module.h"
  27.  
  28. extern Ptr SCCRd : 0x1D8;
  29. extern Ptr SCCWr : 0x1DC;
  30.  
  31. /* my globals for this module */
  32.  
  33. int usercarr[maxport]; /* if TRUE then detect carrier, if not use LAME time out method*/
  34. char maxbaud[maxport][10]; /* the max baudrate for this modem */
  35.  
  36. struct SSS{
  37.         char string[64]; /* this is a struct to pass some variables to the modems module */
  38.         int mode;   /* the mode to use */
  39.         }; 
  40.  
  41.  
  42. pascal void main (mode1,G1,P1)
  43.        int mode1;
  44.        struct GS *G1;
  45.        Ptr P1;
  46. {
  47. Handle temph;
  48. float version = 0.5; /* what version of MUBBS you are compatable with IE: .5 and above */
  49. RememberA0(); SetUpA4(); /* This sets up the A4 register to access our globals */
  50. asm { _RecoverHandle }; asm {move.l a0,temph}; HLock(temph); /* locks our module, do this ! */
  51.  
  52. G=G1; /* This MUST be the first thing you do in main only, it sets up the struct globals */
  53. mode[u]=mode1; /* set up our mode so that you can read it anywhere */
  54.  
  55. switch (mode[u]) { /* any un-handled modes return error from this module */
  56.  
  57.     case 3:
  58.         modem(P1); /* we need our globals, so we LOCK and stay that way */
  59.         G->moduleresult=0;
  60.         goto skip1;        /* DON'T UNLOCK */
  61.         break;
  62.     case 98: /* NOTE that this DOESN'T unlock */
  63.         versionck(version); /* just return after this call, don't modify anything */
  64.         goto skip1;        /* DON'T UNLOCK */
  65.         break;        
  66.     case 0:
  67.         strcpy (G->programmer,"N Hawthorn"); /* show the programmer's name up to 20 chars*/
  68.         setupall(); /* set up the modem globals */
  69.         G->moduleresult=99; /* we put 99 here because we need to be called to CLOSE */
  70.         goto skip1;        /* DON'T UNLOCK */
  71.         break;
  72.     case 1:
  73.         G->moduleresult=0; /* bye bye call, UNLOCK NOW */
  74.         break;
  75.     default:
  76.         G->moduleresult=1; /* return bad code */
  77.     };
  78.  
  79. HUnlock(temph); /* unlocks this module, do this ! */
  80.  
  81. skip1:
  82. RestoreA4(); /* call this when you are all done */
  83. }
  84.  
  85.  
  86. modem(S)
  87. struct SSS *S;
  88. {
  89.  
  90. switch (S->mode){
  91.     case 0:
  92.         connect(S);
  93.         break;
  94.     case 1:
  95.         reset(S);
  96.         break;
  97.     case 2:
  98.         hangup(S);
  99.         break;
  100.     }
  101. }
  102.  
  103.  
  104. connect(S)
  105. struct SSS *S;
  106. { /* mode = 0 for a CONNECT condition, ATA was already sent, figure out what baud */
  107.  
  108. while (TRUE){ /* NUMBERS ARE FOR A USR HST MODEM */
  109.     if (strcmp(S->string,"14\x0D") == 0) { /* result code */
  110.         strcpy(G->userbaud[u],"19200"); /* set the baud rate to 19200 */
  111.         break; /* YOU BETTER HAVE HARDWARE HANDSHAKING FOR THIS BAUD RATE ! */
  112.         }
  113.     if (strcmp(S->string,"13\x0D") == 0) { /* result code */
  114.         strcpy(G->userbaud[u],"9600"); /* set the baud rate to 9600 */
  115.         break;
  116.         }
  117.     if (strcmp(S->string,"10\x0D") == 0) { /* result code */
  118.         strcpy(G->userbaud[u],"2400"); /* set the baud rate to 2400 */
  119.         break;
  120.         }
  121.     if (strcmp(S->string,"5\x0D") == 0) {
  122.         strcpy(G->userbaud[u],"1200"); /* set the baud rate to 1200 */
  123.         break;
  124.         }
  125.     if (strcmp(S->string,"1\x0D") == 0) {
  126.         strcpy(G->userbaud[u],"300"); /* set the baud rate to 300 */
  127.         break;
  128.         }
  129.     S->mode=FALSE; /* show we have a bad baud rate, hang up */
  130.     return;
  131.     }
  132. G->carrdet[u]=usercarr[u]; /* set it up so we detect carrier loss now that we're connected*/
  133. S->mode=TRUE; /* show its OK */
  134.  
  135. /* MUBBS main handles the rest from here, thanks for your help ! */
  136.  
  137. }
  138.  
  139.  
  140. reset(S)
  141. struct SSS *S;
  142. { /* mode = 1 for a modem reset call, send the set up string */
  143. char modemstring[256];
  144. int times;
  145.  
  146. setstuff(modemstring,u); /* get the strings for this line */
  147. G->serclose();
  148. G->seropen();
  149. print("C> Resetting modem on line %d (\"0\" below is OK). This line is now at %s baud\n",(u+1),G->userbaud[u]);
  150. times=0;
  151. while (++times<10) {
  152.     sendnc("AT\r"); /* get it to see the new baud rate */
  153.     wait(2);
  154.     if (showstat()) break;
  155.     sendnc("ATZ\r"); /* get desparate, try modem reset */
  156.     wait(2);
  157.     }
  158.  
  159. times=0;
  160. while (++times<10) {
  161.     sendnc(modemstring); /* NO CHECK OUTPUT DOES NOT CHECK FOR ANYTHING !! */
  162.     wait(2);
  163.     if (showstat() ==1) break; /* make sure it sees a "0" not a "OK" !! */
  164.     wait(2);
  165.     }
  166. if(times >=10) {
  167.     print("C> ERROR! Modem on line %d doesn't want to reset properly!\n",(u+1));
  168.     print("C> !!!!!! Port is set at %s baud, CHECK YOUR MODEM STRINGS!\n",G->userbaud[u]);
  169.     sendnc("ATZ\r"); /* get desparate, try modem reset it may reset next time */
  170.     }
  171. G->serflush(); /* dump any garbage characters */
  172. }
  173.  
  174.  
  175. hangup(S)
  176. struct SSS *S;
  177. {/* mode = 2 for a modem hangup call, try to hang up modem */
  178. int
  179.     temp1 = 0,
  180.     temp2,
  181.     temp3 = 0,
  182.     baud,
  183.     flag = 1;
  184.  
  185. Byte check;
  186. char modemstring[256], savebaud[maxnamelength];
  187.  
  188. strcpy(savebaud,G->userbaud[u]); /* save the current baud rate */
  189. setstuff(modemstring,u); /* get the strings for this line */
  190.  
  191. if (strcmp(maxbaud[u],"300") == 0) baud=5; /* find the max baud */
  192. else if (strcmp(maxbaud[u],"1200") == 0) baud=4; /* this sets it to this after first try */
  193. else if (strcmp(maxbaud[u],"2400") == 0) baud=3;
  194. else if (strcmp(maxbaud[u],"9600") == 0) baud=2;
  195. else if (strcmp(maxbaud[u],"19200") == 0) baud=1;
  196.  
  197. temp2=baud;
  198. strcpy(G->userbaud[u],savebaud); /* recover the current baud rate */
  199.  
  200. while (TRUE) {
  201.     while (temp1++ < 8) {
  202.         if (G->forgetusers && !G->local[u]) return; /* if we are not logged in locally and cancel all users */
  203.         if (usercarr[u]) {
  204.             if (u == 0) {if ((check = *(SCCRd + 2) & 0x20)) return; }/* CTS is bit 5, 1= carr loss */
  205.             if (u == 1) {if ((check = *(SCCRd + 0) & 0x20)) return; }/* CTS is bit 5, 1= carr loss */
  206.             print("C>      CARRIER STILL PRESENT ON LINE %d, HANGING UP !!\n",(u+1));
  207.             }
  208.         else sendnc("Hardware carrier detect cable not installed.]Please hang up now.]"); /* try the good old standard */
  209.         temp3++; /* try at current baud rate first, then goto highest next */
  210.         print("C> Hanging up at %s baud, attempt=%d\n",G->userbaud[u],temp3);
  211.         G->serclose();
  212.         G->seropen();
  213.         wait(2);
  214.         if (flag) {sendnc("\x02\x02\x02");} /* send the ecape code and delay 2 seconds */
  215.         else sendnc("+++"); /* try the good old standard */
  216.         wait(2);
  217.         if (!usercarr[u]) { /* for LAME mode */
  218.             sendnc(modemstring); /* send the reset string, try to hang up now */
  219.             wait(2);
  220.             sendnc("+++"); /* try the good old standard just incase */
  221.             wait(2);
  222.             sendnc("\r"); /* send a return to clear things */
  223.             wait(1);
  224.             }
  225.         showstat(); /* just prints any input to the screen */
  226.         sendnc(modemstring); /* send the reset string */
  227.         wait(1);
  228.         showstat(); /* just prints any input to the screen */
  229.         lll:
  230.         if (temp2 == 1) strcpy(G->userbaud[u],"19200"); /* set the baud rate to 19200 */
  231.         if (temp2 == 2) strcpy(G->userbaud[u],"9600"); /* set the baud rate to 9600 */
  232.         if (temp2 == 3) strcpy(G->userbaud[u],"2400"); /* set the baud rate to 2400 */
  233.         if (temp2 == 4) strcpy(G->userbaud[u],"1200"); /* set the baud rate to 1200 */
  234.         if (temp2 == 5) strcpy(G->userbaud[u],"300"); /* set the baud rate to 300 */
  235.         if (temp2 >= 6 && !usercarr[u]) return; /* if no carrier detect, we tried all assume hung up */
  236.         if (temp2++ >= 6) {
  237.             temp2=baud; /* set it back to the max baud and do it again */
  238.             goto lll;
  239.             }
  240.         }
  241.     flag = ! flag;
  242.     temp1 = 0;
  243.     if (temp3 >= 80) {
  244.         print("\nC>     ERROR !! Tried 80 times to reset modem, COULDN'T RESET LINE %d !!\n",(u+1));
  245.         print("C>     !!!!!!!! CHECK YOUR MODEM STRINGS FOR LINE %d !!\n",(u+1));
  246.         return;
  247.         }
  248.     }
  249. }
  250.  
  251. showstat() /* checks for OK or 0, sends any characters received to Mac screen */
  252. {
  253. char s[256],ck[8],check[8];
  254. int where,theone, x=0, i;
  255.  
  256. strcpy(ck,"0~OK"); /* check for 0 or OK */
  257.  
  258. G->carrdet[u]=FALSE;
  259. while (TRUE){
  260.     i=0;
  261.     while (G->serin()){ /* serin doesn't check for carrier here ! */
  262.         if (G->input[u] == 0x0A) continue;
  263.         print("%c",G->input[u]);
  264.         s[i]=G->input[u];
  265.         if (i++ > 250) break; /* don't overflow s !! */
  266.         }
  267.     s[i]='\0'; /* terminate the string */
  268.     if (searchs (ck,s,check,&where,&theone)) return(theone);
  269.         /* returns 0 if no match, 1 if "0", 2 if "OK" */
  270.     if (x++>5) break; /* if we have waited long enough, forget it! */
  271.     wait(1); /* wait just a bit longer */
  272.     }
  273. return (0);
  274. }
  275.  
  276. setupall(){ /* called up once at start to set up the modem globals */
  277. char modemstring[256];
  278. int user;
  279.  
  280. user=0; /* note that this is not messing with "u" */
  281. do { /* sets the modem globals for each user */
  282.     setstuff(modemstring,user); /* get the strings for this line */
  283.     } while (++user < G->users); /* user = 0 to maxport (counting here starts at 0) */
  284. }
  285.  
  286. setstuff(modemstring,user)
  287. char *modemstring;
  288. int user;
  289. { /* set up strings */
  290. char tempB[11],tempCD[11],tempDTR[11];
  291. int x;
  292. FILE *stream;
  293.  
  294. strcpy(modemstring,"ATH0E0V0M1S0=0S2=2\r"); /* standard modem string, just incase */
  295. strcpy(tempB,"2400"); /* standard 2400, just incase */
  296. strcpy(tempCD,"1"); /* Carrier detect, just incase */
  297. strcpy(tempDTR,"0"); /* No DTR, just incase */
  298.  
  299. if ((stream = fopen(":bbssupport:modems", "r")) == NULL) {
  300.     print("C> FILE ERROR - cannot open :bbssupport:modems\n");
  301.     print("C> SENDING A STANDARD STRING TO THE MODEM !!\n ");
  302.     goto skip;
  303.     }
  304.  
  305.  
  306. for(x=0; x<=user; x++){ /* get this line's modem string */
  307.     if (fscanf(stream,"%10[^,],%10[^,],%10[^\n]\n%255[^\n]\n",tempB,tempCD,tempDTR,modemstring) == EOF) break; /* get the string */
  308.     }
  309.  
  310. fclose(stream);
  311. strcat(modemstring,"\r");
  312.  
  313. skip:
  314. strcpy(G->userbaud[user],tempB); /* set to the MAX baud rate */
  315. strcpy(maxbaud[user],tempB); /* set to the MAX baud rate */
  316. usercarr[user]= strtoint(tempCD); /* see if we are to detect carrier or if it's LAME BBS time */
  317. if(usercarr[user] == 0) usercarr[user]=FALSE;
  318. else usercarr[user]=TRUE;
  319.  
  320. G->usedtr[user]= strtoint(tempDTR); /* Use DTR hang up? Not used here yet, but it's set anyway */
  321. if(G->usedtr[user] == 0) G->usedtr[user]=FALSE;
  322. else G->usedtr[user]=TRUE;
  323. }
  324.  
  325.